/*
Connection SPI au USB-ISS(! attention pas SSP0 ou SSP1)
- SSEL = P0.16 = /CE du USB-ISS
- SCK  = P0.15 = SCK du USB-ISS
- MISO = P0.17 = SDI du USB-ISS
- MOSI = P0.18 = SDO du USB-ISS
 */
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
#include <cr_section_macros.h>
#include <NXP/crp.h>
// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
#include <stdio.h>

volatile uint32_t spi_msg_index;
volatile uint32_t spi_msg_long;
volatile int spi_msg_dispo;
volatile int spi_msg[64];

void SPI_IRQHandler(void);
int main(void)
{
    int i = 0 ;
	printf("SPI Basic\n");
	
	// Mise en route SPI
	LPC_SC->PCONP |= 1<<8;
	// Selection Horloge SPI, ! minimum 8X plus vite que le taux de transfert SPI
	LPC_SC->PCLKSEL0 &= ~(1<<17); // fonction "01" -> PCLK = CCLK
	LPC_SC->PCLKSEL0 |= (1<<16);
	// Config SPI -> fonction "11"
    LPC_PINCON->PINSEL0 |= (1<<31)|(1<<30); // SCK
    LPC_PINCON->PINSEL1 |= (1<<1)|(1<<0)|(1<<3)|(1<<2)|(1<<5)|(1<<4); // SSEL, MISO, MOSI
    // Config en Pull-Up -> fonction "00"
	LPC_PINCON->PINMODE0 &= ~((1<<31)|(1<<30)); // Pull-up SCK
	LPC_PINCON->PINMODE1 &= ~((1<<1)|(1<<0)|(1<<3)|(1<<2)|(1<<5)|(1<<4));  // Pull-up SSEL, MISO, MOSI
	// SPI Data Number of bits selected by bit 11,10,9,8
	LPC_SPI->SPCR |= (1<<2);
	// CPHA, CLK Phase active High
	LPC_SPI->SPCR &= ~(1<<3);
	// CPOL, CLK active High
	LPC_SPI->SPCR &= ~(1<<4);
	// Slave mode
	LPC_SPI->SPCR &= ~(1<<5);
	// transfert MSB
	LPC_SPI->SPCR &= ~(1<<6);
	// hardware IRQ
	LPC_SPI->SPCR |= (1<<7);
	// 8 bit
	LPC_SPI->SPCR |= 1<<11;
	LPC_SPI->SPCR &= ~(1<<10);
	LPC_SPI->SPCR &= ~(1<<9);
	LPC_SPI->SPCR &= ~(1<<8);
/*
	// 16 bit
	LPC_SPI->SPCR &= ~(1<<11);
	LPC_SPI->SPCR &= ~(1<<10);
	LPC_SPI->SPCR &= ~(1<<9);
	LPC_SPI->SPCR &= ~(1<<8);
*/

	spi_msg_dispo = 0;
	spi_msg_index = 0;
	spi_msg_long = 0;

	NVIC_EnableIRQ(SPI_IRQn);

	printf("Attente activite SPI...\n");

	while(1)
    {
		if ( spi_msg_dispo == 1)
		{
			printf("MSG=");
			for(i=0; i < spi_msg_long; i++)
				printf(" %d ", spi_msg[i]);
			printf("\n");
	     spi_msg_long = 0;
		 spi_msg_dispo = 0;
		 spi_msg_index = 0;
		}
 	}
	return 0 ;
}

void SPI_IRQHandler(void)
{
	//  ! Lecture obligatoire de SPSR ET SPDR pour RAZ du bit SPIF du statut
	LPC_SPI->SPINT |= 1<<0; // RAZ Int
	if ( (LPC_SPI->SPSR & (1<<7)) == (1<<7) )
	{
		if ( spi_msg_long == 0 ) // nouveau msg ?
		{
			// le premier byte donne la longueur du msg
			spi_msg_long = (LPC_SPI->SPDR & 0xff);
			spi_msg_index = 0;
			return;
		}
	  // donnee
      spi_msg[spi_msg_index] = (LPC_SPI->SPDR & 0xff);
      spi_msg_index++;
      // nombre de donnees atteint ?
      if ( spi_msg_index == spi_msg_long )
      {
    	  spi_msg_dispo = 1;
    	  return;
      }
	}
	// ! printf dans la routine IRQ SPI provoquent un Read Overrun !
	//printf("STATUS REG= %d\n", LPC_SPI->SPSR);
}
